package org.example;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.yaml.snakeyaml.Yaml;

import java.io.*;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

public class DeepSeekClient {
    public static String API_KEY;

    private static final String BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";
    private static String MODEL;

//    private static final String BASE_URL = "https://api.deepseek.com";
//    private static final String MODEL = "deepseek-reasoner";


    private static final String AUTO_PATH = "src/main/resources/conversations/auto/";
    private static final String MANUAL_PATH = "src/main/resources/conversations/manual/";

    // 用于存储当前对话的文件名
    private static String currentConversationFile;

    // 判断是否是第一句话
    private static boolean ONE_FLAG = true;

    public static void main(String[] args) {
        // 1. 加载 YAML 配置文件
        Yaml yaml = new Yaml();
        try (InputStream input = DeepSeekClient.class.getClassLoader().getResourceAsStream("application.yml")) {
            if (input == null) {
                System.err.println("找不到配置文件: application.yml");
                return;
            }

            // 2. 解析 YAML 内容为 Map
            Map<String, Object> config = yaml.load(input);

            // 3. 获取 deepseek.api_key
            Map<String, Object> deepseekConfig = (Map<String, Object>) config.get("deepseek");
            if (deepseekConfig == null || !deepseekConfig.containsKey("api_key")) {
                System.err.println("配置项 deepseek.api_key 未设置");
                return;
            }

            API_KEY = (String) deepseekConfig.get("api_key");
            System.out.println("API Key 已加载: " + API_KEY);

        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("读取配置文件失败: " + e.getMessage());
        }


        try (Scanner scanner = new Scanner(System.in)) {
            List<ChatMessage> messages = new ArrayList<>();

            while (true) {
                System.out.println("\n请选择模型：1. deepseek-R10528 2.deepseek-v3");

                // 处理非整数输入的情况
                if (!scanner.hasNextInt()) {
                    System.out.println("请输入有效数字！");
                    scanner.next(); // 清除无效输入
                    continue;       // 继续循环
                }

                String input = scanner.nextLine().trim();
                int caseInt = Integer.parseInt(input);
                switch (caseInt) {
                    case 1:
                        MODEL = "deepseek-r1-0528";
                        break;
                    case 2:
                        MODEL = "deepseek-v3";
                        break;
                    default:
                        System.out.println("请添加模型");
                        continue; // 直接跳到循环开头重新选择
                }

                // 成功选择后退出循环
                break;
            }

            while (true) {


                System.out.println("\n对话开始（输入1退出，输入2保存，输入3加载，输入4新建对话，输入5重新回答，输入6回退，输入7角色扮演，0+entrer发送信息）:");
                System.out.print("\n用户: ");
                String userInput = scanner.nextLine();
                userInput = userInput.trim();
                if ("1".equalsIgnoreCase(userInput)) {
                    System.out.print("是否保存当前对话？(y/n): ");
                    String choice = scanner.nextLine();
                    if ("y".equalsIgnoreCase(choice)) {
                        saveMessages(scanner, messages);
                    }
                    System.out.println("对话已结束");
                    break;
                } else if ("2".equalsIgnoreCase(userInput)) {
                    saveMessages(scanner, messages);
                } else if ("3".equalsIgnoreCase(userInput)) {
                    messages = loadMessages(scanner, messages);
                    System.out.println("历史对话");
                    messages.forEach(System.out::println);
                } else if ("4".equalsIgnoreCase(userInput)) {
                    messages.clear();
                    ONE_FLAG = true;
                } else if ("5".equalsIgnoreCase(userInput)) {

                    // 删除最后一次的消息，是ai回答消息
                    if (messages.isEmpty()) {
                        System.out.println("请先输入问题");
                    } else {
                        messages.remove(messages.size() - 1); // 删除AI回答消息

                        // 获取AI回复
                        String response = sendRequest(messages);

                        // 添加AI回复到对话历史
                        messages.add(new ChatMessage("assistant", response));
                        // 自动保存当前对话
                        autoSaveConversation(messages);
                    }
                } else if ("6".equalsIgnoreCase(userInput)) {

                    if (messages.isEmpty()) {
                        System.out.println("请先输入问题");
                    } else {
                        // 查询所有的用户提问
                        List<ChatMessage> messageUserList = messages.stream().filter(c -> "user".equals(c.getRole())).collect(Collectors.toList());
                        HashMap<Integer, Integer> numAndIndexMap = new HashMap<>();
                        int num = 1;
                        for (int i = 0; i < messages.size(); i++) {
                            ChatMessage chatMessage = messages.get(i);
                            if (chatMessage.getRole().equals("user")){
                                numAndIndexMap.put(num++,i);
                            }
                        }
                        int start = 1;
                        for (ChatMessage chatMessage : messageUserList) {

                            System.out.println(start++ + ":" + chatMessage.getContent());
                        }
                        int choice;
                        // 保留数字及之前的问答
                        while (true) {
                            try {
                                System.out.print("\n请输入数字: ");
                                choice = scanner.nextInt();
                                if (choice >= 1 && choice <= messageUserList.size())
                                    break;
                                System.out.println("请选择正确数字");
                            } catch (InputMismatchException e) {
                                System.out.println("请输入有效数字");
                                scanner.next(); // 清除无效输入
                            }
                        }
                        // 加2是因为，sublist不包尾+1，ai回答+1
                        messages = messages.subList(0, numAndIndexMap.get(choice)+2);

                        // 另外保存对话
                        generateNewConversationFile(messages.get(0).getContent());
                        autoSaveConversation(messages);
                    }
                }else if ("7".equalsIgnoreCase(userInput)) {
                    System.out.print("请输入背景故事或者设定，0结束：");
                    StringBuilder message = new StringBuilder();
                    while (true) {
                        String line = scanner.nextLine(); // 直接读取新输入
                        if ("0".equals(line)) {
                            break;
                        }
                        message.append(line).append("\n");
                    }
                    // 添加系统消息到对话历史
                    messages.add(new ChatMessage("system", message.toString()));
                    if (ONE_FLAG) {
                        generateNewConversationFile(message.toString());
                        ONE_FLAG = false;
                    }
                    autoSaveConversation(messages);
                    System.out.println("\n已保存背景信息");
                } else {
                    StringBuilder message = new StringBuilder();
                    while (true) {
                        message.append(userInput).append("\n");
                        userInput = scanner.nextLine();
                        if ("0".equals(userInput)) {
                            break;
                        }
                    }
                    // 添加用户消息到对话历史
                    messages.add(new ChatMessage("user", message.toString()));
                    if (ONE_FLAG) {
                        generateNewConversationFile(message.toString());
                        ONE_FLAG = false;
                    }


                    // 获取AI回复
                    String response = sendRequest(messages);

                    // 添加AI回复到对话历史
                    messages.add(new ChatMessage("assistant", response));
                    // 自动保存当前对话
                    autoSaveConversation(messages);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void saveMessages(Scanner scanner, List<ChatMessage> messages) {
        System.out.print("请输入保存的文件名: ");
        String filename = scanner.nextLine();
        Path dir = Paths.get(MANUAL_PATH);
        try {
            Files.createDirectories(dir);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        try (FileWriter writer = new FileWriter(MANUAL_PATH + filename)) {
            Gson gson = new GsonBuilder().setPrettyPrinting().create(); // 格式化输出
            gson.toJson(messages, writer); // 将对象列表写入 JSON
            System.out.println("对话已保存到: " + filename);
        } catch (IOException e) {
            System.err.println("保存失败: " + e.getMessage());
        }
    }

    private static List<ChatMessage> loadMessages(Scanner scanner, List<ChatMessage> currentMessages) {
        System.out.print("请输入要加载的文件名: ");
        String filename = scanner.nextLine();

        try (FileReader reader = new FileReader(filename)) {
            Gson gson = new Gson();
            List<ChatMessage> loadedMessages = gson.fromJson(reader, new TypeToken<List<ChatMessage>>() {
            }.getType());
            System.out.println("对话已加载自: " + filename);
            return loadedMessages;
        } catch (FileNotFoundException e) {
            System.err.println("文件未找到: " + e.getMessage());
        } catch (IOException e) {
            System.err.println("读取文件时发生错误: " + e.getMessage());
        } catch (Exception e) {
            System.err.println("JSON 解析失败或数据格式不匹配: " + e.getMessage());
        }

        // 如果加载失败，返回当前消息列表，保持状态不变
        return currentMessages;
    }

    // 自动生成新对话的文件名
    private static void generateNewConversationFile(String message) {
        // 截取消息前10个字符，超过部分添加省略号
        String baseName = message;
        if (baseName.length() > 10) {
            baseName = baseName.substring(0, 10) + "...";
        }
        // 过滤非法字符（如 < > : * ? " | \ / 等）
        baseName = sanitizeFileName(baseName);
        // 生成日期时间戳（格式：yyMMddHHmmss）
        String timestamp = new SimpleDateFormat("MMddHHmm").format(new Date());

        // 构造文件名（示例：abc..._240505123045_0.json）
        String filename = String.format("%s_%s.json", timestamp, baseName);

        // 目录路径
        Path dir = Paths.get(AUTO_PATH);
        try {
            Files.createDirectories(dir); // 若目录不存在则创建
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 设置当前对话文件路径
        currentConversationFile = dir.resolve(filename).toString();
    }

    /**
     * 替换文件名中的非法字符为下划线
     */
    private static String sanitizeFileName(String input) {
        return input.replaceAll("[\\\\/\n:*?\"<>|]", "");
    }

    // 自动保存当前对话到指定文件
    private static void autoSaveConversation(List<ChatMessage> messages) {
        if (currentConversationFile == null) {
            System.out.println("\n尚未初始化对话文件，请先新建对话");
            return;
        }

        try (FileWriter writer = new FileWriter(currentConversationFile)) {
            Gson gson = new GsonBuilder().setPrettyPrinting().create();
            gson.toJson(messages, writer);
            System.out.println("对话已自动保存到: " + currentConversationFile);
        } catch (IOException e) {
            System.err.println("自动保存失败: " + e.getMessage());
        }
    }

    private static String sendRequest(List<ChatMessage> messages) throws IOException, JSONException {
        URL url = new URL(BASE_URL + "/chat/completions");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Authorization", "Bearer " + API_KEY);
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setDoOutput(true);

        JSONObject jsonBody = new JSONObject();
        jsonBody.put("model", MODEL);
        jsonBody.put("messages", convertToJSONArray(messages));
        jsonBody.put("stream", true);

        try (OutputStream os = conn.getOutputStream()) {
            byte[] input = jsonBody.toString().getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        StringBuilder responseBuilder = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;
        boolean flag1 = true;
        boolean flag2 = true;
        while ((line = reader.readLine()) != null) {
            if (line.startsWith("data: ")) {
                String data = line.substring(5);
                if (!"[DONE]".equals(data.trim())) {
                    JSONObject chunk = null;
                    try {
                        chunk = new JSONObject(data);

                        JSONObject choice = chunk.getJSONArray("choices").getJSONObject(0);
                        JSONObject delta = choice.getJSONObject("delta");
                        String reasoningContent = "null";
                        if ("deepseek-r1-0528".equals(MODEL)){

                            reasoningContent = delta.getString("reasoning_content");
                        }
                        String content = delta.getString("content");
                        if (!"null".equals(reasoningContent)) {
                            if (flag1) {
                                System.out.println("\n-------------------------------深度思考-------------------------------");
                                flag1 = false;
                            }
                            responseBuilder.append(reasoningContent);
                            System.out.print(reasoningContent);
                        } else if (!"null".equals(content)) {
                            if (flag2) {
                                System.out.println("\n-------------------------------正式回答-------------------------------");
                                flag2 = false;
                            }
                            responseBuilder.append(content);
                            System.out.print(content);
                        } else {
                            if (flag1) {
                                System.out.println("\n-------------------------------深度思考-------------------------------");
                                flag1 = false;
                            }
                            responseBuilder.append(reasoningContent);
                            System.out.print(reasoningContent);
                        }
                    } catch (JSONException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        System.out.println("\n");

        reader.close();
        return responseBuilder.toString();
    }

    private static JSONArray convertToJSONArray(List<ChatMessage> messages) throws JSONException {
        JSONArray array = new JSONArray();
        for (ChatMessage message : messages) {
            JSONObject obj = new JSONObject();
            obj.put("role", message.getRole());
            obj.put("content", message.getContent());
            array.put(obj);
        }
        return array;
    }

}
